package com.tasks.server;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.apache.log4j.Logger;

import com.tasks.enums.Enum;

public class Executor {
	
	private Statement 	stmt	= null;	
	private ResultSet 	rs		= null;
	private Server 		server	= null;
	
	static Logger logger = Logger.getLogger(Executor.class);

	public Executor(Server s) {
		stmt = s.getStatement();
		server = s;
	}
	
	public void close()
	{
		try
        {
            Exception e = null;
            try
			{
	        	if (rs != null)
	            {
	                rs.close();
	                rs = null;
	            }
			}
            catch (Exception ex)
			{
            	e = ex;
            	rs = null;
			}

            try
			{
	            if (stmt != null)
	            {
	                stmt.close();
	                stmt = null;
	            }
			}
            catch (Exception ex)
			{
            	if (e == null)
            	{
            		e = ex;
            	}
            	stmt = null;
			}

            if (e != null)
            {
            	throw e;
            }
		}
        catch (Exception e)
        {
            new ServerException(this, "close", e);
        }
	}
	
	public Integer executeInsert(String sql)
	{
		try 
		{
			logger.debug(sql);
			stmt.execute(sql);
			if(server.getDBType() == Server.MYSQL_DB)
			{
				execute("SELECT LAST_INSERT_ID() AS ID");	
			}
			else if (server.getDBType() == Server.SQLITE_DB)
			{
				execute("SELECT LAST_INSERT_ROWID() AS ID");
			}			
			return getInt("ID");
		} 
		catch (SQLException e) 
		{
			new ServerException(this, "execute", e);
		}
		return 0;
	}
	
	public boolean executeUpdate(String sql)
	{
		try 
		{
			logger.debug(sql);
			return stmt.execute(sql);
		} 
		catch (SQLException e) 
		{
			new ServerException(this, "execute", e);
		}
		return false;
	}
	
	public ResultSet executeRS(String sql)
	{
		try 
		{		
			logger.debug(sql);
			return stmt.executeQuery(sql);
		} 
		catch (SQLException e) 
		{
			new ServerException(this, "execute", e);
		}
		return null; 
	}
	
	public boolean execute(String sql) 
	{
		try 
		{
			logger.debug(sql);
			stmt.execute(sql);			
			rs = stmt.getResultSet();			
			return server.getDBType() == Server.SQLITE_DB ? rs.isBeforeFirst() : rs.next();
		} 
		catch (SQLException e) 
		{
			new ServerException(this, "execute", e);
		}
		return false;
	}
	
	public boolean next()
	{
		try 
		{
			return rs.next();
		} 
		catch (SQLException e) {
			return false;
		}
	}
	
//	public boolean isNullResults() 
//	{
//		try 
//		{
//			return rs.isBeforeFirst();
//		} 
//		catch (SQLException e) 
//		{
//			new ServerException(this, "isNullResults", e);
//		}
//		return false;
//	}
	
	public Integer getInt(String column) 
	{
		try 
		{
			return new Integer(rs.getInt(column));
		} 
		catch (SQLException e)
		{
			new ServerException(this, "getInt", e);
		}
		return null;
	}
	
	public Boolean getBoolean(String column)
	{
		try 
		{
			return new Boolean(rs.getBoolean(column));
		} 
		catch (SQLException e) 
		{
			new ServerException(this, "getBoolean", e);
		}
		return null;
	}
	
	public Enum getEnum(String column)
	{
		try 
		{
			return Enum.newInstance(column, rs.getInt(column));
		} 
		catch (SQLException e) 
		{
			new ServerException(this, "getEnum", e);
		}
		return null;
	}
	
	public String getString(String column)
	{
		try 
		{
			return rs.getString(column);
		} 
		catch (Exception e) 
		{
			new ServerException(this, "getString", e);
		}
		return null;
	}
	
	public DateTime getDateTime(String column) 
	{
		try 
		{
			return rs.getString(column) == null ? null : new DateTime(rs.getString(column));
		} 
		catch (Exception e)
		{
			new ServerException(this, "getDateTime", e);
		}
		return null;
	}
}
